objectdef ezvg_NonCmbt inherits Act
{

  ;############################################
  ;##
  ;##  DO NOT FUCK WITH THE FOLLOWING
  ;##
  ;############################################
  
  variable uint nextCheckT
  
  variable int64 tgtLootCorpse
  variable int64 tgtHarvestCorpse
  variable int64 tgtMob
  variable bool InvChanged
  
  variable bool amHarvesting
  
  variable uint lastAssistT
  
  method Initialize()
  {
    This[parent]:Initialize
    This.InvChanged:Set[TRUE]
  }
  
  method Shutdown()
  {
  }

  method changeNextT(float modT)
  {
    This.nextCheckT:Set[${Math.Calc[${Script.RunningTime}+(${modT}*1000)]}]
  }

  member:bool isReady()
  {
    if ${This.nextCheckT} > ${Script.RunningTime}
      return FALSE
    return TRUE
  }

  method changeTgt(int64 tgtID)
  {
    Pawn[id, ${tgtID}]:Target
    This:changeNextT[0.250]
  }
  
  method Assist()
  {
    if ${This.lastAssistT}>${Script.RunningTime}
      return
    else
    {                                              
      if ${Me.DTarget.ID}!=${AssistID}
        This:changeTgt[${AssistID}]
      VGExecute /assist
      This.lastAssistT:Set[${Math.Calc[${Script.RunningTime}+500]}]
      This:changeNextT[0.250]
    }
  }
  
  member:bool ValidHP()
  {
    if !${Me.Target(exists)} || ${Me.Target.Type.Equal[Resource]}
      return FALSE
    if ( ${Me.TargetHealth}<=${EngagePct} || ${Combat.CommandAssist} ) && ${Me.TargetHealth}>0 && ${Me.Target.IsAttackable} && ( !${Me.Target.IsDead} || ( ${Me.Chunk.DisplayName.Equal[Sands of Sorrow]} && ${Me.TargetHealth}>0 ) )
      return TRUE
    return FALSE
  }

  member:bool OwnerCheckByID(int64 pawnID)
  {
    if !${Pawn[ID, ${pawnID}](exists)}
      return FALSE
    if ${Pawn[ID, ${pawnID}].Owner(exists)}
    {
      if ${Group[${Pawn[ID, ${pawnID}].Owner.Name}](exists)} || ${Pawn[ID, ${pawnID}].OwnedByMe}
        return TRUE
      else
        return FALSE
    }
    return TRUE
  }

  member:bool OwnerCheck()
  {
    if !${Me.Target(exists)}
      return FALSE
    if ${Me.Target.Owner(exists)}
    {
      if ${Group[${Me.Target.Owner.Name}](exists)} || ${Me.Target.OwnedByMe}
        return TRUE
      else
        return FALSE
    }
    return TRUE
  }
  
  member:bool ValidCombatTgt()
  {
    ;echo objMov: ValidCombatTgt check
    if ${This.OwnerCheck} && ${This.ValidHP}
      return TRUE
    return FALSE  
  }
  
  member:bool ValidPullTgt(int64 tgtMob, int dist)
  {
    if ${Pawn[ID, ${tgtMob}].Distance}>${dist} || ${Pawn[ID, ${tgtMob}].CheckCollision(exists)} || !${Pawn[ID, ${tgtMob}].IsAttackable}
      return FALSE
    if  ${Pawn[ID, ${tgtMob}].IsDead}
      return FALSE
    if ${Pawn[ID, ${tgtMob}].Level}<${minLvlPull} || ${Pawn[ID, ${tgtMob}].Level}>${maxLvlPull}
      return FALSE
    if ${This.OwnerCheckByID[${tgtMob}]}
      return TRUE
    else
      return FALSE
  }

  member:bool ValidResourceTgt(int64 resID, int dist)
  {
    if ${resID.Equal[0]} || !${Pawn[ID, ${resID}](exists)}
      return FALSE
    if ${Pawn[ID, ${resID}].Distance} > ${dist}
      return FALSE
    if ${This.OwnerCheckByID[${resID}]} && !${Pawn[ID, ${resID}].Name.Left[6].Equal[remain]} && ${Pawn[ID, ${resID}].IsHarvestable} && !${LavishSettings[HarvestList].FindSetting[${resID}](exists)}
      return TRUE
    return FALSE
  }
  
  member:bool ValidLootTgt()
  {
    if ${This.OwnerCheckByID[${Pawn[Corpse].ID}]} && ( ${Pawn[Corpse].ContainsLoot} || ( ${Pawn[Corpse].Name.Left[6].Equal[remain]} && ${Pawn[Corpse].IsHarvestable} ) ) && !${LavishSettings[LootList].FindSetting[${Pawn[Corpse].ID}](exists)}
      return TRUE
    return FALSE
  }
  
  member:bool LootMobClose(int dist)
  {
    if ${Pawn[Corpse].Distance}<=${dist} && ${This.ValidLootTgt}
    {
      This.tgtLootCorpse:Set[${Pawn[Corpse].ID}]
      return TRUE
    }
    return FALSE
  }

  member:bool ResourceClose(int dist)
  {
    if ${This.ValidResourceTgt[${Pawn[Resource].ID}, ${dist}]}
    {
      This.tgtHarvestCorpse:Set[${Pawn[Resource].ID}]
      return TRUE  
    }
    if ${This.ValidResourceTgt[${Pawn[Corpse].ID}, ${dist}]}
    {
      This.tgtHarvestCorpse:Set[${Pawn[Corpse].ID}]
      return TRUE  
    }
    return FALSE
  }

  member:bool AggroNPCClose(int dist)
  {
    variable int64 pullMob
    if ${Pawn[AggroNPC](exists)} && ${doPull}
    {
      if ${This.ValidPullTgt[${Pawn[AggroNPC].ID}, ${dist}]}
        pullMob:Set[${Pawn[AggroNPC].ID}]
    }
    if ${Pawn[NPC](exists)} && ${doPullNPC}
    {
      if ${This.ValidPullTgt[${Pawn[NPC].ID}, ${dist}]}
      {
        if ${pullMob}!=0
        {
          if ${Pawn[ID, ${pullMob}].Distance}>${Pawn[NPC].Distance}
            pullMob:Set[${Pawn[NPC].ID}]
        }
        else
          pullMob:Set[${Pawn[NPC].ID}]
      }
    }
    if ${pullMob}!=0
    {
      This.tgtMob:Set[${pullMob}]
      return TRUE
    }
    else
      return FALSE
  }
  
  ;############################################
  ;##
  ;##  THIS SHIT YOU CAN DICK AROUND WITH
  ;##
  ;############################################
  
  method LogicPulse()
  {
    ;;echo --- obj_NonCmbt:LogicPulseAct ---
    if ${Script.RunningTime}>=${This.nextCheckT}
    {
      if ${Me.ToPawn.IsDead} && ${Me.Health.Equal[0]}
      {
        VGExecute /rezaccept
        This:changeNextT[1.00]
        return
      }
      elseif ${Paused} || ${Me.ToPawn.IsStunned} || ${Me.IsCasting} || !${Me.Ability[Auto Attack].IsReady} || ( ${Me.InCombat} && ${This.ValidCombatTgt} )
        return
      elseif ${Me.IsLooting} && ( ${doLoot} || ${doLootOnly} )
        This:LootLogic
      else
        This:nonCombatLogic
    }
  }

  method nonCombatLogic()
  {
    ; We know that we are not in combat, not dead and not casting
    ; Are we looting?  Do we have a target that we shouldn't?  Should we have
    ; a target but don't?
    ; Should we be running through our nonCombat routines?
    This[parent].didAction:Set[FALSE]
    ;if !${Me.Target(exists)} && ${Me.Encounter.Equal[0]} && ${Me.Ability[Auto Attack].Toggled}
    ;  This[parent]:useAutoAtk
    if ( ${doLoot} || ${doLootOnly} )
    {
      if ${This.LootMobClose[${scanLootRng}]}
        This:LootLogic
    }
    if ${Me.ToPawn.CombatState.Equal[0]}
    {
      if ${Me.Class.Equal[Bard]} && ${doNonCombatSong} && ${Songs[${nonCombatSong}](exists)} && !${Me.Effect[${Me.FName}'s Bard Song - "${nonCombatSong}"](exists)} && !${Mov.isMoving}
        Songs[${nonCombatSong}]:Perform
      if ${doItemCanni} && ${Me.EnergyPct}<=${canniEnerPct} && ${Me.HealthPct}>=${canniHPPct}
        This[parent]:useItem["canni"]
      if ${doSelfBuff} && !${This[parent].didAction}
        This[parent]:useAbil["buff", ${Me.ToPawn.ID}]
      if ${doItemSelfBuff} && !${This[parent].didAction}
        This[parent]:useItem["buff"]
      if ${doRez} && !${This[parent].didAction}
        This:RezLogic
      if ${doHeal} && !${This[parent].didAction}
        This:HealLogic
      if ${doCanni} && !${This[parent].didAction} && ${Me.EnergyPct}<=${canniEnerPct} && ${Me.HealthPct}>=${canniHPPct}
        This[parent]:useAbil["canni"]
      if ${Me.Class.Equal[Druid]}
      {
        if ${Me.Inventory[Great Roseberries].Quantity}<4 || ${Me.Inventory[Large Mottleberries].Quantity}<4
          This[parent]:doUseAbil["Bountiful Harvest", ${Me.ToPawn.ID}]
        elseif ${Me.Inventory[Fireseeds].Quantity}<4
          This[parent]:doUseAbil["Fireseeds", ${Me.ToPawn.ID}]
      }
      if !${This[parent].didAction} && ${doGroupBuff} && ${Me.IsGrouped}
        This:GroupBuffLogic
      if ( ${doPet} || ${doMinion} ) && !${This[parent].didAction}
        This:PetLogic
    }
    if ${doAssist} && ( ${Me.Encounter}>0 || ${Pawn[ID, ${AssistID}].CombatState}!=0 )
    {
      if ${Me.FName.NotEqual[${Assist}]} && ${Pawn[ID, ${AssistID}].CombatState}!=0
        This:Assist
      elseif ${Me.FName.Equal[${Assist}]} || ( ${doPull} && !${huntPaused} )
      {
        if ${This.AggroNPCClose[${pullDist}]}
          This:AggroNPCLogic 
      }
    }
    elseif !${huntPaused} && ( ${doPull} || ${doPullNPC} )
    {
      if ${This.AggroNPCClose[${pullDist}]}
        This:AggroNPCLogic 
    }
    if !${This[parent].didAction} && ( ${doHarvest} || ( ${doResources} && !${huntPaused} ) )
    {
      if ${Me.FName.NotEqual[${Assist}]} && ${doHarvest} && ${Pawn[ID, ${AssistID}].CombatState}!=0
        This:ResourceLogic
      elseif ${doResources} && !${huntPaused}
      {
        if ${This.ResourceClose[5]}
          This:ResourceLogic
      }
    }
    if ${doDeleteTrash} && ${This.InvChanged}
      This:DeleteTrashLogic
    if ${Script.RunningTime}>${This.nextCheckT}
      This:changeNextT[0.125]
  }
  
  ;+++++++++++++++++++++++++++++++++++++++++++++++++
  ;++
  ;++      BENEFICIAL ABILITY USE
  ;++
  ;+++++++++++++++++++++++++++++++++++++++++++++++++
  
  method HealLogic()
  {
    variable int iterGrpCnt = 1
    variable int grpInRng = 0
    variable int lowGrpMem = 0
    if ${Me.IsGrouped}
    {
      do
      {
        if ${Group[${iterGrpCnt}](exists)}
        {
          if ${doGroupHeal} && ${Group[${iterGrpCnt}].Health}<=${healGrpPct} && ${Group[${iterGrpCnt}].Distance}<=10 && !${Group[${iterGrpCnt}].ToPawn.IsDead}
            grpInRng:Inc[1]
          if ${Group[${iterGrpCnt}].ID}!=${TankID} && ${Group[${iterGrpCnt}].Health}<=${healBigPct} && ${Group[${iterGrpCnt}].Health}>0 && ${Group[${iterGrpCnt}].Distance}<25
          {
            if ${lowGrpMem}==0
              lowGrpMem:Set[${iterGrpCnt}]
            elseif ${Group[${iterGrpCnt}].Health}<${Group[${lowGrpMem}].Health}
              lowGrpMem:Set[${iterGrpCnt}]
          }
        }
        iterGrpCnt:Inc[1]
      }
      while ${Group[${iterGrpCnt}](exists)}
    }
    if ${healGrpMinInRng}<=${grpInRng} && ${doGroupHeal}
      This[parent]:useAbil["healgrp", ${Me.ToPawn.ID}]
    if !${This[parent].didAction} && ${Me.HealthPct}<=${healMedPct}
      This[parent]:useAbil["healmed", ${Me.ToPawn.ID}]
    if !${This[parent].didAction}
    {
      if ${Me.IsGrouped} && ${Group[${Tank}](exists)}
      {
        if ( ${Group[${Tank}].Health}<=${healBigPct} || ( ${Group[${Tank}].Health}<=${healHOTPct} && ${doHOT} )) && ${Pawn[id, ${TankID}](exists)} && !${Pawn[id, ${TankID}].IsDead}
        {
          if ${Group[${Tank}].Health}<=${healEmgPct}
            This[parent]:useAbil["healemg", ${TankID}]
          elseif ${Group[${Tank}].Health}<=${healBigPct}
            This[parent]:useAbil["healbig", ${TankID}]
          elseif ${doHOT} && ${Group[${Tank}].Health}<=${healHOTPct}
            This[parent]:useAbil["healhot", ${TankID}]
        }
        if !${This[parent].didAction} && ${Me.IsGrouped} && ${lowGrpMem}>0 && (( ${Group[${lowGrpMem}].Health}<=${healHOTPct} && ${doHOT} ) || ${Group[${lowGrpMem}].Health}<=${healMedPct} )
        {
          if ${Group[${lowGrpMem}].Health}<=${healEmgPct}
            This[parent]:useAbil["healemg", ${Group[${lowGrpMem}].ID}]
          elseif ${Group[${lowGrpMem}].Health}<=${healMedPct}
            This[parent]:useAbil["healmed", ${Group[${lowGrpMem}].ID}]
          elseif ${doHOT} && ${Group[${lowGrpMem}].Health}<=${healHOTPct}
            This[parent]:useAbil["healhot", ${Group[${lowGrpMem}].ID}]
        }
      }
      elseif ${Me.DTarget.ID}!=${TankID} && ${Pawn[AggroNPC].Distance}<=30
        This:changeTgt[${TankID}]
      elseif !${Me.IsGrouped} && ${Me.DTarget.ID.Equal[${TankID}]}
      {
        if ${Me.DTargetHealth}<=${healEmgPct}
          This[parent]:useAbil["healemg", ${TankID}]
        elseif ${Me.DTargetHealth}<=${healMedPct}
          This[parent]:useAbil["healmed", ${TankID}]
        elseif ${Me.DTargetHealth}<=${healBigPct}
          This[parent]:useAbil["healbig", ${TankID}]
        elseif ${doHOT} && ${Me.DTargetHealth}<=${healHOTPct}
          This[parent]:useAbil["healhot", ${TankID}]
      }
    }
  }

  method GroupBuffLogic()
  {
    variable int grpIter
    grpIter:Set[1]
    do
    {
      if ${Me.FName.Equal[${Group[${grpIter}]}]}
        This[parent]:useAbil["groupbuff", ${Me.ToPawn.ID}]
      else
        This[parent]:useAbil["groupbuff", ${Group[${grpIter}].ID}]
      grpIter:Inc[1]
    }
    while !${This[parent].didAction} && ${Group[${grpIter}](exists)}
  }
  
  method RezLogic()
  {
    if !${Me.Class.Equal[Cleric]} && !${Me.Class.Equal[Disciple]} && !${Me.Class.Equal[Shaman]} && !${Me.Class.Equal[Blood Mage]}
      return
    variable int curGrpMem
    variable int needsRez
    needsRez:Set[0]
    curGrpMem:Set[1]
    do
    { 
      if ${Group[${curGrpMem}].Health}==0 && ${Group[${curGrpMem}].ToPawn.IsDead}
        needsRez:Set[${curGrpMem}]
      curGrpMem:Inc[1]
    }
    while ${Group[${curGrpMem}](exists)} && ${needsRez.Equal[0]}
    if ${needsRez}>0
      This:RezWhich[${Group[${needsRez}].ID}]
    elseif ${needsRez.Equal[0]}
    {
      if ${Pawn[ID, ${TankID}].IsDead}
        This:RezWhich[${TankID}]  
      elseif ${Pawn[ID, ${AssistID}].IsDead}
        This:RezWhich[${AssistID}]  
      elseif ${Pawn[ID, ${FollowID}].IsDead}
        This:RezWhich[${FollowID}]  
    }
    
  }
  
  method RezWhich(int64 toonID)
  {
    if ${Me.InCombat} && ${Me.Ability[${combatRez}].IsReady}
      This:doUseAbil[${combatRez}, ${toonID}]
    elseif !${Me.InCombat} && ${Me.Ability[${nonCombatRez}].IsReady}
      This:doUseAbil[${nonCombatRez}, ${toonID}]
  }

  ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  ;@@
  ;@@      OTHER LOGIC
  ;@@
  ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  method LootLogic()
  {
    ; loot mob exists and should loot, dont know distance or destination
    variable iterator iter
    if ${Me.IsLooting}
    {
      if ${Mov.isMoving}
        Mov:Stop
      if ${doLoot} || ${Me.Target.Name.Find[${Me.FName}]}
      {
        LavishSettings[LootList]:AddSetting[${Loot.LootingFrom.ID}, ${Loot.LootingFrom.ID}]
        Loot:LootAll
      }
      elseif ${doLootOnly}
      {
        LavishSettings[LootList]:AddSetting[${Loot.LootingFrom.ID}, ${Loot.LootingFrom.ID}]
        lootOnly:GetSettingIterator[iter]
        iter:First
        while ( ${iter.Key(exists)} )
        {
          if ${Loot.Item[${iter.Key}](exists)}
            Loot.Item[${iter.Key}]:Loot
          iter:Next
        }
      }
      Loot:EndLooting
      VGExecute /cleartargets
      This:changeNextT[0.250]
    }
    elseif ${Pawn[ID, ${This.tgtLootCorpse}].Distance}<5 && !${LavishSettings[LootList].FindSetting[${This.tgtLootCorpse}]}
    {
      Pawn[ID, ${This.tgtLootCorpse}]:Loot
      This:changeNextT[0.250]
    }
  }

  method ResourceLogic()
  {
    ; Harvesting reads as InCombat, so only need to worry about
    ; assisting on the right harvesting node/corpse and choosing
    ; the right one if I'm the assist.
    if ${Me.FName.NotEqual[${Assist}]}
      This:Assist
    elseif ( !${Me.Target(exists)} || ${This.tgtHarvestCorpse}!=${Me.Target.ID} )
      This:changeTgt[${This.tgtHarvestCorpse}]
    if ${Me.Target(exists)} && ${Me.Target.IsHarvestable} && ${This.OwnerCheckByID[${Me.Target.ID}]} && !${Me.Target.Name.Left[6].Equal[remain]} && !${LavishSettings[HarvestList].FindSetting[${Me.Target.ID}](exists)}
    {
      if ${This.amHarvesting} && ${Me.Target.Name.Left[6].Equal[remain]}
      {
        LavishSettings:AddSetting[${Me.Target.ID}, ${Me.Target.ID}]
        This.amHarvesting:Set[FALSE]
        VGExecute /cleartargets
        This:changeNextT[0.25]
      }  
      elseif ${Me.Target.Distance}<5 && ${Me.ToPawn.CombatState}==0
      {
        if ${Mov.isMoving}
          Mov:Stop
        if ${LavishSettings[LootList].FindSetting[${Me.Target.ID}](exists)}
          LavishSettings[LootList].FindSetting[${Me.Target.ID}]:Remove
        This.amHarvesting:Set[TRUE]
        This[parent]:useAutoAtk
        This:changeNextT[0.25]
      }
    }
  }
  
  method AggroNPCLogic()
  {
    ;echo ---objNonCombat:AggroNPCLogic
    if ${Me.FName.NotEqual[${Assist}]} || ( !${doPull} && !${doPullNPC} && !${huntPaused} )
      This:Assist
    elseif ( ( ${doPull} || ${doPullNPC} ) && !${huntPaused} ) || ${Me.FName.Equal[${Assist}]}
    {
      ; echo ---objNonCombat:AggroNPCLogic we are pulling or we are the assist ${Pawn[ID, ${This.tgtMob}].Name} with ID ${This.tgtMob}
      if !${Me.Target(exists)} || ${Me.Target.ID}!=${This.tgtMob}
        This:changeTgt[${This.tgtMob}]
      elseif ${Me.Target.Distance}<=${pullDist}
        This[parent]:useAbil["pull", ${Me.Target.ID}]
    }
  }
  
  method PetLogic()
  {
    if ${doPet} && !${Me.HavePet}
    {
      This.petAttacking:Set[FALSE]
      This.petAlive:Set[FALSE]
      if ${Me.Ability[${summonPet}](exists)} && ${Me.Ability[${summonPet}].IsReady}
        This:doUseAbil[${summonPet}]
    }
    elseif ${Me.HavePet} && !${This.petAlive}
    {
      This.petAlive:Set[TRUE]
      VGExecute /pet assistmealways
    }
    elseif ${doMinion} && ${Me.Minion}<${numMinionsToSummon}
      This:doUseAbil[${summonMinion}]
  }
  
  method DeleteTrashLogic()
  {
    variable iterator itemIter
    invTrash:GetSettingIterator[itemIter]
    itemIter:First
    while ( ${itemIter.Key(exists)} )
    {
      if ${Me.Inventory[${itemIter.Key}](exists)}
        Me.Inventory[${itemIter.Key}]:Delete[all]
      itemIter:Next
    }
    This.InvChanged:Set[FALSE]
  }
  
}

variable ezvg_NonCmbt NonCmbt